package com.cloud.security;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cloud.constant.AuthConstants;
import com.cloud.dao.user.UserMapper;
import com.cloud.exception.ValidateException;
import com.cloud.pojo.user.UserInfo;
import com.cloud.service.LoginService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

@Component("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    private static final Logger LOG = LoggerFactory.getLogger(UserDetailsService.class.getName());

    @Resource
    private LoginService loginService;

    @Resource
    private UserMapper userMapper;

    @Value("${business.synchronize.fingerprint.day.num}")
    private Integer syncDayNum;

    @Override
    public UserDetails loadUserByUsername(String param) throws UsernameNotFoundException {
        // 切割username
        String[] params = param.split(";");
        String username = params[0];
        String fingerprintCode = params[1];
        UserInfo userInfo = loginService.findUserByUsername(username);
        if (userInfo == null) throw new UsernameNotFoundException("User " + username + " was not found in db");

        // 只能在注册帐号的设备上登录
        if(!userInfo.getFingerprintCode().equals(fingerprintCode)) {
            LOG.error("用户库的指纹: {}, 浏览器存的指纹: {}", userInfo.getFingerprintCode(), fingerprintCode);
            if(userInfo.getSynchronizeFingerprintTimeLast() != null
                    && new Date().after(DateUtil.offsetDay(userInfo.getSynchronizeFingerprintTimeLast(), syncDayNum))){
                // 更新同步指纹
                UpdateWrapper update = new UpdateWrapper();
                update.eq("username", username);
                update.set("synchronize_fingerprint_time", userInfo.getSynchronizeFingerprintTimeLast());
                update.set("synchronize_fingerprint_time_last", new Date());
                update.set("fingerprint_code", fingerprintCode);
                userMapper.update(null, update);
            }else {
                throw new ValidateException("只能在注册帐号的设备上登录!");
            }
        }

        // 更新登录用户的信息
        UpdateWrapper update = new UpdateWrapper();
        update.eq("username", username);
        update.set("last_login_time", new Date());
        Integer loginCount = userInfo.getLoginCount();
        update.set("login_count", ++loginCount);
        if(userInfo.getLoginCount().equals(AuthConstants.LOGIN_THRESHOLD)) {
            update.set("role", AuthConstants.VISITOR);
        }
        userMapper.update(null, update);

        // 定义权限列表
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>() {{
            add(new SimpleGrantedAuthority(userInfo.getRole()));
        }};

        // 封装UserDetail详情
        return new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
    }

}
